<?xml version='1.0' encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <link href="cpip.css" rel="stylesheet" type="text/css" />
    <title>File: /Users/paulross/dev/Python-3.6.2/Include/pyhash.h</title>
  </head>
  <body>
    <h1>File: /Users/paulross/dev/Python-3.6.2/Include/pyhash.h</h1>
    <p>Green shading in the line number column
means the source is part of the translation unit, red means it is conditionally excluded.
Highlighted line numbers link to the translation unit page. Highlighted macros link to
the macro page.</p>
    <pre><a name="1" /><span class="True">       1:</span> <span class="f">#</span><span class="n">ifndef</span> <a href="macros_noref.html#_UHlfSEFTSF9IXzA_"><span class="b">Py_HASH_H</span></a>
<a name="2" /><span class="True">       2:</span> 
<a name="3" /><span class="True">       3:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_UHlfSEFTSF9IXzA_"><span class="b">Py_HASH_H</span></a>
<a name="4" /><span class="False">       4:</span> <span class="f">#</span><span class="n">ifdef</span> <span class="b">__cplusplus</span>
<a name="5" /><span class="False">       5:</span> <span class="m">extern</span> <span class="e">&quot;C&quot;</span> <span class="f">{</span>
<a name="6" /><span class="True">       6:</span> <span class="f">#</span><span class="n">endif</span>
<a name="7" /><span class="True">       7:</span> 
<a name="8" /><span class="True">       8:</span> <span class="k">/* Helpers for hash functions */</span>
<a name="9" /><span class="True">       9:</span> <span class="f">#</span><span class="n">ifndef</span> <span class="b">Py_LIMITED_API</span>
<a name="10" /><span class="True">      10:</span> <a href="macros_ref.html#_UHlBUElfRlVOQ18w"><span class="b">PyAPI_FUNC</span></a><span class="f">(</span><span class="b">Py_hash_t</span><span class="f">)</span> <span class="b">_Py_HashDouble</span><span class="f">(</span><span class="m">double</span><span class="f">)</span><span class="f">;</span>
<a name="11" /><span class="True">      11:</span> <a href="macros_ref.html#_UHlBUElfRlVOQ18w"><span class="b">PyAPI_FUNC</span></a><span class="f">(</span><span class="b">Py_hash_t</span><span class="f">)</span> <span class="b">_Py_HashPointer</span><span class="f">(</span><span class="m">void</span><span class="f">*</span><span class="f">)</span><span class="f">;</span>
<a name="12" /><span class="True">      12:</span> <a href="macros_ref.html#_UHlBUElfRlVOQ18w"><span class="b">PyAPI_FUNC</span></a><span class="f">(</span><span class="b">Py_hash_t</span><span class="f">)</span> <span class="b">_Py_HashBytes</span><span class="f">(</span><span class="m">const</span> <span class="m">void</span><span class="f">*</span><span class="f">,</span> <span class="b">Py_ssize_t</span><span class="f">)</span><span class="f">;</span>
<a name="13" /><span class="True">      13:</span> <span class="f">#</span><span class="n">endif</span>
<a name="14" /><span class="True">      14:</span> 
<a name="15" /><span class="True">      15:</span> <span class="k">/* Prime multiplier used in string and various other hashes. */</span>
<a name="16" /><span class="True">      16:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_X1B5SEFTSF9NVUxUSVBMSUVSXzA_"><span class="b">_PyHASH_MULTIPLIER</span></a> <span class="c">1000003UL</span>  <span class="k">/* 0xf4243 */</span>
<a name="17" /><span class="True">      17:</span> 
<a name="18" /><span class="True">      18:</span> <span class="k">/* Parameters used for the numeric hash implementation.  See notes for</span>
<a name="19" /><span class="True">      19:</span> <span class="k">   _Py_HashDouble in Objects/object.c.  Numeric hashes are based on</span>
<a name="20" /><span class="True">      20:</span> <span class="k">   reduction modulo the prime 2**_PyHASH_BITS - 1. */</span>
<a name="21" /><span class="True">      21:</span> 
<a name="22" /><span class="True">      22:</span> <span class="f">#</span><span class="n">if</span> <a href="macros_ref.html#_U0laRU9GX1ZPSURfUF8w"><span class="b">SIZEOF_VOID_P</span></a> <span class="f">&gt;=</span> <span class="c">8</span>
<a name="23" /><span class="True">      23:</span> <span class="f">#</span>  <span class="n">define</span> <a href="macros_noref.html#_X1B5SEFTSF9CSVRTXzA_"><span class="b">_PyHASH_BITS</span></a> <span class="c">61</span>
<a name="24" /><span class="False">      24:</span> <span class="f">#</span><span class="n">else</span>
<a name="25" /><span class="False">      25:</span> <span class="f">#</span>  <span class="n">define</span> <a href="macros_noref.html#_X1B5SEFTSF9CSVRTXzA_"><span class="b">_PyHASH_BITS</span></a> <span class="c">31</span>
<a name="26" /><span class="True">      26:</span> <span class="f">#</span><span class="n">endif</span>
<a name="27" /><span class="True">      27:</span> 
<a name="28" /><span class="True">      28:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_X1B5SEFTSF9NT0RVTFVTXzA_"><span class="b">_PyHASH_MODULUS</span></a> <span class="f">(</span><span class="f">(</span><span class="f">(</span><span class="b">size_t</span><span class="f">)</span><span class="c">1</span> <span class="f">&lt;&lt;</span> <a href="macros_noref.html#_X1B5SEFTSF9CSVRTXzA_"><span class="b">_PyHASH_BITS</span></a><span class="f">)</span> <span class="f">-</span> <span class="c">1</span><span class="f">)</span>
<a name="29" /><span class="True">      29:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_X1B5SEFTSF9JTkZfMA__"><span class="b">_PyHASH_INF</span></a> <span class="c">314159</span>
<a name="30" /><span class="True">      30:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_X1B5SEFTSF9OQU5fMA__"><span class="b">_PyHASH_NAN</span></a> <span class="c">0</span>
<a name="31" /><span class="True">      31:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_X1B5SEFTSF9JTUFHXzA_"><span class="b">_PyHASH_IMAG</span></a> <a href="macros_noref.html#_X1B5SEFTSF9NVUxUSVBMSUVSXzA_"><span class="b">_PyHASH_MULTIPLIER</span></a>
<a name="32" /><span class="True">      32:</span> 
<a name="33" /><span class="True">      33:</span> 
<a name="34" /><span class="True">      34:</span> <span class="k">/* hash secret</span>
<a name="35" /><span class="True">      35:</span> <span class="k"> *</span>
<a name="36" /><span class="True">      36:</span> <span class="k"> * memory layout on 64 bit systems</span>
<a name="37" /><span class="True">      37:</span> <span class="k"> *   cccccccc cccccccc cccccccc  uc -- unsigned char[24]</span>
<a name="38" /><span class="True">      38:</span> <span class="k"> *   pppppppp ssssssss ........  fnv -- two Py_hash_t</span>
<a name="39" /><span class="True">      39:</span> <span class="k"> *   k0k0k0k0 k1k1k1k1 ........  siphash -- two uint64_t</span>
<a name="40" /><span class="True">      40:</span> <span class="k"> *   ........ ........ ssssssss  djbx33a -- 16 bytes padding + one Py_hash_t</span>
<a name="41" /><span class="True">      41:</span> <span class="k"> *   ........ ........ eeeeeeee  pyexpat XML hash salt</span>
<a name="42" /><span class="True">      42:</span> <span class="k"> *</span>
<a name="43" /><span class="True">      43:</span> <span class="k"> * memory layout on 32 bit systems</span>
<a name="44" /><span class="True">      44:</span> <span class="k"> *   cccccccc cccccccc cccccccc  uc</span>
<a name="45" /><span class="True">      45:</span> <span class="k"> *   ppppssss ........ ........  fnv -- two Py_hash_t</span>
<a name="46" /><span class="True">      46:</span> <span class="k"> *   k0k0k0k0 k1k1k1k1 ........  siphash -- two uint64_t (*)</span>
<a name="47" /><span class="True">      47:</span> <span class="k"> *   ........ ........ ssss....  djbx33a -- 16 bytes padding + one Py_hash_t</span>
<a name="48" /><span class="True">      48:</span> <span class="k"> *   ........ ........ eeee....  pyexpat XML hash salt</span>
<a name="49" /><span class="True">      49:</span> <span class="k"> *</span>
<a name="50" /><span class="True">      50:</span> <span class="k"> * (*) The siphash member may not be available on 32 bit platforms without</span>
<a name="51" /><span class="True">      51:</span> <span class="k"> *     an unsigned int64 data type.</span>
<a name="52" /><span class="True">      52:</span> <span class="k"> */</span>
<a name="53" /><span class="True">      53:</span> <span class="f">#</span><span class="n">ifndef</span> <span class="b">Py_LIMITED_API</span>
<a name="54" /><span class="True">      54:</span> <span class="m">typedef</span> <span class="m">union</span> <span class="f">{</span>
<a name="55" /><span class="True">      55:</span>     <span class="k">/* ensure 24 bytes */</span>
<a name="56" /><span class="True">      56:</span>     <span class="m">unsigned</span> <span class="m">char</span> <span class="b">uc</span><span class="f">[</span><span class="c">24</span><span class="f">]</span><span class="f">;</span>
<a name="57" /><span class="True">      57:</span>     <span class="k">/* two Py_hash_t for FNV */</span>
<a name="58" /><span class="True">      58:</span>     <span class="m">struct</span> <span class="f">{</span>
<a name="59" /><span class="True">      59:</span>         <span class="b">Py_hash_t</span> <span class="b">prefix</span><span class="f">;</span>
<a name="60" /><span class="True">      60:</span>         <span class="b">Py_hash_t</span> <span class="b">suffix</span><span class="f">;</span>
<a name="61" /><span class="True">      61:</span>     <span class="f">}</span> <span class="b">fnv</span><span class="f">;</span>
<a name="62" /><span class="True">      62:</span>     <span class="k">/* two uint64 for SipHash24 */</span>
<a name="63" /><span class="True">      63:</span>     <span class="m">struct</span> <span class="f">{</span>
<a name="64" /><span class="True">      64:</span>         <span class="b">uint64_t</span> <span class="b">k0</span><span class="f">;</span>
<a name="65" /><span class="True">      65:</span>         <span class="b">uint64_t</span> <span class="b">k1</span><span class="f">;</span>
<a name="66" /><span class="True">      66:</span>     <span class="f">}</span> <span class="b">siphash</span><span class="f">;</span>
<a name="67" /><span class="True">      67:</span>     <span class="k">/* a different (!) Py_hash_t for small string optimization */</span>
<a name="68" /><span class="True">      68:</span>     <span class="m">struct</span> <span class="f">{</span>
<a name="69" /><span class="True">      69:</span>         <span class="m">unsigned</span> <span class="m">char</span> <span class="b">padding</span><span class="f">[</span><span class="c">16</span><span class="f">]</span><span class="f">;</span>
<a name="70" /><span class="True">      70:</span>         <span class="b">Py_hash_t</span> <span class="b">suffix</span><span class="f">;</span>
<a name="71" /><span class="True">      71:</span>     <span class="f">}</span> <span class="b">djbx33a</span><span class="f">;</span>
<a name="72" /><span class="True">      72:</span>     <span class="m">struct</span> <span class="f">{</span>
<a name="73" /><span class="True">      73:</span>         <span class="m">unsigned</span> <span class="m">char</span> <span class="b">padding</span><span class="f">[</span><span class="c">16</span><span class="f">]</span><span class="f">;</span>
<a name="74" /><span class="True">      74:</span>         <span class="b">Py_hash_t</span> <span class="b">hashsalt</span><span class="f">;</span>
<a name="75" /><span class="True">      75:</span>     <span class="f">}</span> <span class="b">expat</span><span class="f">;</span>
<a name="76" /><span class="True">      76:</span> <span class="f">}</span> <span class="b">_Py_HashSecret_t</span><span class="f">;</span>
<a name="77" /><span class="True">      77:</span> <a href="macros_ref.html#_UHlBUElfREFUQV8w"><span class="b">PyAPI_DATA</span></a><span class="f">(</span><span class="b">_Py_HashSecret_t</span><span class="f">)</span> <span class="b">_Py_HashSecret</span><span class="f">;</span>
<a name="78" /><span class="True">      78:</span> <span class="f">#</span><span class="n">endif</span>
<a name="79" /><span class="True">      79:</span> 
<a name="80" /><span class="True">      80:</span> <span class="f">#</span><span class="n">ifdef</span> <a href="macros_ref.html#_UHlfREVCVUdfMA__"><span class="b">Py_DEBUG</span></a>
<a name="81" /><span class="True">      81:</span> <a href="macros_ref.html#_UHlBUElfREFUQV8w"><span class="b">PyAPI_DATA</span></a><span class="f">(</span><span class="m">int</span><span class="f">)</span> <span class="b">_Py_HashSecret_Initialized</span><span class="f">;</span>
<a name="82" /><span class="True">      82:</span> <span class="f">#</span><span class="n">endif</span>
<a name="83" /><span class="True">      83:</span> 
<a name="84" /><span class="True">      84:</span> 
<a name="85" /><span class="True">      85:</span> <span class="k">/* hash function definition */</span>
<a name="86" /><span class="True">      86:</span> <span class="f">#</span><span class="n">ifndef</span> <span class="b">Py_LIMITED_API</span>
<a name="87" /><span class="True">      87:</span> <span class="m">typedef</span> <span class="m">struct</span> <span class="f">{</span>
<a name="88" /><span class="True">      88:</span>     <span class="b">Py_hash_t</span> <span class="f">(</span><span class="f">*</span><span class="m">const</span> <span class="b">hash</span><span class="f">)</span><span class="f">(</span><span class="m">const</span> <span class="m">void</span> <span class="f">*</span><span class="f">,</span> <span class="b">Py_ssize_t</span><span class="f">)</span><span class="f">;</span>
<a name="89" /><span class="True">      89:</span>     <span class="m">const</span> <span class="m">char</span> <span class="f">*</span><span class="b">name</span><span class="f">;</span>
<a name="90" /><span class="True">      90:</span>     <span class="m">const</span> <span class="m">int</span> <span class="b">hash_bits</span><span class="f">;</span>
<a name="91" /><span class="True">      91:</span>     <span class="m">const</span> <span class="m">int</span> <span class="b">seed_bits</span><span class="f">;</span>
<a name="92" /><span class="True">      92:</span> <span class="f">}</span> <span class="b">PyHash_FuncDef</span><span class="f">;</span>
<a name="93" /><span class="True">      93:</span> 
<a name="94" /><span class="True">      94:</span> <a href="macros_ref.html#_UHlBUElfRlVOQ18w"><span class="b">PyAPI_FUNC</span></a><span class="f">(</span><span class="b">PyHash_FuncDef</span><span class="f">*</span><span class="f">)</span> <span class="b">PyHash_GetFuncDef</span><span class="f">(</span><span class="m">void</span><span class="f">)</span><span class="f">;</span>
<a name="95" /><span class="True">      95:</span> <span class="f">#</span><span class="n">endif</span>
<a name="96" /><span class="True">      96:</span> 
<a name="97" /><span class="True">      97:</span> 
<a name="98" /><span class="True">      98:</span> <span class="k">/* cutoff for small string DJBX33A optimization in range [1, cutoff).</span>
<a name="99" /><span class="True">      99:</span> <span class="k"> *</span>
<a name="100" /><span class="True">     100:</span> <span class="k"> * About 50% of the strings in a typical Python application are smaller than</span>
<a name="101" /><span class="True">     101:</span> <span class="k"> * 6 to 7 chars. However DJBX33A is vulnerable to hash collision attacks.</span>
<a name="102" /><span class="True">     102:</span> <span class="k"> * NEVER use DJBX33A for long strings!</span>
<a name="103" /><span class="True">     103:</span> <span class="k"> *</span>
<a name="104" /><span class="True">     104:</span> <span class="k"> * A Py_HASH_CUTOFF of 0 disables small string optimization. 32 bit platforms</span>
<a name="105" /><span class="True">     105:</span> <span class="k"> * should use a smaller cutoff because it is easier to create colliding</span>
<a name="106" /><span class="True">     106:</span> <span class="k"> * strings. A cutoff of 7 on 64bit platforms and 5 on 32bit platforms should</span>
<a name="107" /><span class="True">     107:</span> <span class="k"> * provide a decent safety margin.</span>
<a name="108" /><span class="True">     108:</span> <span class="k"> */</span>
<a name="109" /><span class="True">     109:</span> <span class="f">#</span><span class="n">ifndef</span> <a href="macros_noref.html#_UHlfSEFTSF9DVVRPRkZfMA__"><span class="b">Py_HASH_CUTOFF</span></a>
<a name="110" /><span class="True">     110:</span> <span class="f">#</span>  <span class="n">define</span> <a href="macros_noref.html#_UHlfSEFTSF9DVVRPRkZfMA__"><span class="b">Py_HASH_CUTOFF</span></a> <span class="c">0</span>
<a name="111" /><span class="False">     111:</span> <span class="f">#</span><span class="n">elif</span> <span class="f">(</span><a href="macros_noref.html#_UHlfSEFTSF9DVVRPRkZfMA__"><span class="b">Py_HASH_CUTOFF</span></a> <span class="f">&gt;</span> <span class="c">7</span> <span class="f">||</span> <a href="macros_noref.html#_UHlfSEFTSF9DVVRPRkZfMA__"><span class="b">Py_HASH_CUTOFF</span></a> <span class="f">&lt;</span> <span class="c">0</span><span class="f">)</span>
<a name="112" /><span class="False">     112:</span> <span class="f">#</span>  <span class="n">error</span> <a href="macros_noref.html#_UHlfSEFTSF9DVVRPRkZfMA__"><span class="b">Py_HASH_CUTOFF</span></a> <span class="b">must</span> <span class="b">in</span> <span class="b">range</span> <span class="c">0...7.</span>
<a name="113" /><span class="True">     113:</span> <span class="f">#</span><span class="n">endif</span> <span class="k">/* Py_HASH_CUTOFF */</span>
<a name="114" /><span class="True">     114:</span> 
<a name="115" /><span class="True">     115:</span> 
<a name="116" /><span class="True">     116:</span> <span class="k">/* hash algorithm selection</span>
<a name="117" /><span class="True">     117:</span> <span class="k"> *</span>
<a name="118" /><span class="True">     118:</span> <span class="k"> * The values for Py_HASH_SIPHASH24 and Py_HASH_FNV are hard-coded in the</span>
<a name="119" /><span class="True">     119:</span> <span class="k"> * configure script.</span>
<a name="120" /><span class="True">     120:</span> <span class="k"> *</span>
<a name="121" /><span class="True">     121:</span> <span class="k"> * - FNV is available on all platforms and architectures.</span>
<a name="122" /><span class="True">     122:</span> <span class="k"> * - SIPHASH24 only works on plaforms that don&apos;t require aligned memory for integers.</span>
<a name="123" /><span class="True">     123:</span> <span class="k"> * - With EXTERNAL embedders can provide an alternative implementation with::</span>
<a name="124" /><span class="True">     124:</span> <span class="k"> *</span>
<a name="125" /><span class="True">     125:</span> <span class="k"> *     PyHash_FuncDef PyHash_Func = {...};</span>
<a name="126" /><span class="True">     126:</span> <span class="k"> *</span>
<a name="127" /><span class="True">     127:</span> <span class="k"> * XXX: Figure out __declspec() for extern PyHash_FuncDef.</span>
<a name="128" /><span class="True">     128:</span> <span class="k"> */</span>
<a name="129" /><span class="True">     129:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_UHlfSEFTSF9FWFRFUk5BTF8w"><span class="b">Py_HASH_EXTERNAL</span></a> <span class="c">0</span>
<a name="130" /><span class="True">     130:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_UHlfSEFTSF9TSVBIQVNIMjRfMA__"><span class="b">Py_HASH_SIPHASH24</span></a> <span class="c">1</span>
<a name="131" /><span class="True">     131:</span> <span class="f">#</span><span class="n">define</span> <a href="macros_noref.html#_UHlfSEFTSF9GTlZfMA__"><span class="b">Py_HASH_FNV</span></a> <span class="c">2</span>
<a name="132" /><span class="True">     132:</span> 
<a name="133" /><span class="True">     133:</span> <span class="f">#</span><span class="n">ifndef</span> <a href="macros_noref.html#_UHlfSEFTSF9BTEdPUklUSE1fMA__"><span class="b">Py_HASH_ALGORITHM</span></a>
<a name="134" /><span class="True">     134:</span> <span class="f">#</span>  <span class="n">ifndef</span> <span class="b">HAVE_ALIGNED_REQUIRED</span>
<a name="135" /><span class="True">     135:</span> <span class="f">#</span>    <span class="n">define</span> <a href="macros_noref.html#_UHlfSEFTSF9BTEdPUklUSE1fMA__"><span class="b">Py_HASH_ALGORITHM</span></a> <a href="macros_noref.html#_UHlfSEFTSF9TSVBIQVNIMjRfMA__"><span class="b">Py_HASH_SIPHASH24</span></a>
<a name="136" /><span class="False">     136:</span> <span class="f">#</span>  <span class="n">else</span>
<a name="137" /><span class="False">     137:</span> <span class="f">#</span>    <span class="n">define</span> <a href="macros_noref.html#_UHlfSEFTSF9BTEdPUklUSE1fMA__"><span class="b">Py_HASH_ALGORITHM</span></a> <a href="macros_noref.html#_UHlfSEFTSF9GTlZfMA__"><span class="b">Py_HASH_FNV</span></a>
<a name="138" /><span class="True">     138:</span> <span class="f">#</span>  <span class="n">endif</span> <span class="k">/* uint64_t &amp;&amp; uint32_t &amp;&amp; aligned */</span>
<a name="139" /><span class="True">     139:</span> <span class="f">#</span><span class="n">endif</span> <span class="k">/* Py_HASH_ALGORITHM */</span>
<a name="140" /><span class="True">     140:</span> 
<a name="141" /><span class="False">     141:</span> <span class="f">#</span><span class="n">ifdef</span> <span class="b">__cplusplus</span>
<a name="142" /><span class="False">     142:</span> <span class="f">}</span>
<a name="143" /><span class="True">     143:</span> <span class="f">#</span><span class="n">endif</span>
<a name="144" /><span class="True">     144:</span> 
<a name="145" /><span class="True">     145:</span> <span class="f">#</span><span class="n">endif</span> <span class="k">/* !Py_HASH_H */</span>
<a name="146" /><span class="True">     146:</span> </pre>
  </body>
</html>
